/*
 * Mat3.h
 *
 *  Created on: 29.09.2009
 *      Author: christoph
 */

#ifndef MAT3_H_
#define MAT3_H_

#include "System.h"
#include "Math.h"
#include "types/Vec3.h"

namespace mehari {
namespace common {

template < typename Real >
class Mat3 {
public:
	Mat3();
	Mat3( const Real r0, const Real r1, const Real r2, const Real r3, const Real r4, const Real r5, const Real r6, const Real r7, const Real r8 );
	Mat3( const Real matrix[9] );
	Mat3( const Mat3& m3 );
	~Mat3();

	void setZero();
	void setIdentity();

	// access
	const Real* operator[] ( int iRow ) const;
	Real* operator [] ( int iRow );
	Real operator () ( int iRow, int iCol ) const;
	Real& operator () ( int iRow, int ICol );

	void setRow( int iRow, const Vec3<Real>& v3Val );
	void setCol( int iCol, const Vec3<Real>& v3Val );

	Vec3<Real> getRow( int iRow ) const;
	Vec3<Real> getCol( int iCol ) const;

	// assignment
	Mat3<Real>& operator = ( const Mat3<Real>& mRhs );

	// arithmetic operations
	Mat3<Real> operator + ( const Mat3<Real>& m3Rhs ) const;
	Mat3<Real> operator - ( const Mat3<Real>& m3Rhs ) const;
	Mat3<Real> operator * ( const Real rRhs ) const;
	Mat3<Real> operator / ( const Real rRhs ) const;

	Mat3<Real> operator += ( const Mat3<Real>& m3Rhs );
	Mat3<Real> operator -= ( const Mat3<Real>& m3Rhs );
	Mat3<Real> operator *= ( const Real rRhs );
	Mat3<Real> operator /= ( const Real rRhs );

	// comparison operations
	bool operator == ( const Mat3<Real>& m3Rhs ) const;
	bool operator != ( const Mat3<Real>& m3Rhs ) const;
	bool operator <  ( const Mat3<Real>& m3Rhs ) const;
	bool operator <= ( const Mat3<Real>& m3Rhs ) const;
	bool operator >  ( const Mat3<Real>& m3Rhs ) const;
	bool operator >= ( const Mat3<Real>& m3Rhs ) const;

	// geometric operations
	Mat3<Real> transpose() const;
	Mat3<Real> inverse() const;
	Mat3<Real> adjoint() const;
	Real determinant() const;

	// Mat3 * Vec3
	Vec3<Real> operator * ( const Vec3<Real>& v3Rhs ) const;

private:
	/**
	 * holds the data
	 * 0 1 2
	 * 3 4 5
	 * 6 7 8
	 */
	Real data[9];
};

#include "../../src/types/Mat3.cpp.inl"

typedef Mat3<float> Mat3f;
typedef Mat3<double> Mat3d;

} // namespace common
} // namespace mehari



#endif /* MAT3_H_ */
